package com.maiyuren.fishkit.ui.components

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ScrollableTabRow
import androidx.compose.material3.Tab
import androidx.compose.material3.TabPosition
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.MutableLiveData
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

private val headHeight: Dp = 54.dp;

interface FishTabDelegate {
    fun onCount(): Int;
    fun onTabTitle(index: Int): String;

    @Composable
    fun onTabContentView(index: Int);
}

private val MAX_PAGE = Int.MAX_VALUE;

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun FishTab(
    modifier: Modifier = Modifier,
    index: MutableLiveData<Int>, // 当前INDEX
    delegate: FishTabDelegate,
    showHeader: Boolean = true) {
    var defaultIndex = getMidPos(index.value!!, delegate.onCount());

    var tabState = rememberPagerState(defaultIndex)

    val scope = rememberCoroutineScope()
    LaunchedEffect(key1 = tabState, block = {
        snapshotFlow { tabState.currentPage }.collect {
            index.value = it % delegate.onCount();
        }
    })

    index.observeForever {
        scope.launch {
            val tempC = tabState.currentPage % delegate.onCount()
            val tempIt = it % delegate.onCount()
            if (tempC != tempIt) {
                tabState.scrollToPage(getMidPos(it, delegate.onCount()))
            }
        }
    }

    Column(modifier = modifier) {
        if (showHeader) {
            genScrollableTabRow(index, delegate, tabState, scope)
        }

        HorizontalPager(
            pageCount = MAX_PAGE,
            state = tabState
        ) {it->
            Column(
                modifier = Modifier.fillMaxSize(),
            ) {
                delegate.onTabContentView(index = it % delegate.onCount())
            }
        }
    }
}

private fun getMidPos(pos: Int, count: Int): Int {
    val newPos = pos + 1000 * count
    if (newPos >= MAX_PAGE) return pos
    return newPos
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun genScrollableTabRow(
    index: MutableLiveData<Int>,
    delegate: FishTabDelegate,
    tabState: PagerState,
    scope: CoroutineScope
) {
    ScrollableTabRow(
        selectedTabIndex = tabState.currentPage % delegate.onCount(),
        modifier = Modifier
            .fillMaxWidth()
            .height(headHeight),
        edgePadding = 0.dp,
        indicator = { tabPositions: List<TabPosition> ->
            Box(
                Modifier
                    .tabIndicatorOffset(tabPositions[tabState.currentPage % delegate.onCount()])
                    .fillMaxSize()
                    .padding(horizontal = 4.dp)

            ) {
                Box(
                    Modifier
                        .fillMaxWidth()
                        .height(4.dp)
                        .padding(horizontal = 20.dp)
                        .background(
                            color = MaterialTheme.colorScheme.primary,
                            shape = RoundedCornerShape(5.dp)
                        )
                        .align(Alignment.BottomCenter)
                )
            }
        },
        divider = { }
    ) {
        for(i in 0 until delegate.onCount()) {
            Tab(modifier = Modifier
                .padding(horizontal = 4.dp)
                .clip(RoundedCornerShape(16.dp)),
                selected = i == tabState.currentPage % delegate.onCount(),
                onClick = {
                    scope.launch {
                        tabState.scrollToPage(getMidPos(i, delegate.onCount()))
                    }
                }
            ) {
                Text(text=delegate.onTabTitle(i), modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp))
            }
        }
    }
}